package com.seleniti.enpareja.web.desktop.server.model.integration.service.impl.appengine;

import java.security.NoSuchAlgorithmException;
import java.util.List;

import javax.jdo.JDOHelper;

import org.ioc.commons.utils.jdo.JdoQueryHelper;
import org.ioc.commons.utils.logs.Log4JFormatterLogger;

import com.seleniti.enpareja.controller.common.domain.Page;
import com.seleniti.enpareja.controller.common.exception.EnParejaException;
import com.seleniti.enpareja.controller.model.integration.database.domain.User;
import com.seleniti.enpareja.web.desktop.server.common.util.CryptoUtils;

public class GAEUserService extends GAEService {
	/**
	 * Logger for this class
	 */
	private static final Log4JFormatterLogger logger = Log4JFormatterLogger.getLogger(GAEUserService.class);

	public GAEUserService() {
		logger.info("GAE Couple service instance");
	}

	public User find(String userId) {
		return userId != null ? pm.getObjectById(User.class, userId) : null;
	}

	public boolean checkIfExists(String userEmail) {

		JdoQueryHelper qh = JdoQueryHelper.newQuery(pm, User.class);

		qh.andParams("userEmail==%s", userEmail);
		qh.setResult("count(this)");

		Number total = (Number) qh.execute();

		return total != null && total.intValue() >= 1;
	}

	public User save(User user, boolean changePassword) throws EnParejaException {

		/*
		 * Only new users can be created without being logged in
		 */
		if (JDOHelper.isPersistent(user)) {
			assertThisLoggedUser(user, "Save user");
		}

		try {
			if (changePassword) {
				user.setPassword(CryptoUtils.encrypt(user.getPassword()));
			}

			pm.makePersistent(user);

			logger.info("User saved: {0}", user);

		} catch (NoSuchAlgorithmException e) {
			throw new EnParejaException(EnParejaException.ErrorCode.PASSWORD_ENCRYPTION_FAILURE, e);
		}

		return user;
	}

	public void delete(User user) throws EnParejaException {
		assertLoggedIn("Delete user");

		pm.deletePersistent(user);
	}

	public Page<User> getAllUsersPage(long start, long length, boolean excludeLoggedUser) {
		return getUsersPageByEmail(null, start, length, excludeLoggedUser);
	}

	public Page<User> getUsersPageByEmail(String filterText, long start, long length, boolean excludeLoggedUser) {

		logger.info("Getting users page by email filtering by '{0}' from {1} to {2}...", filterText, start, length);

		Page<User> page = new Page<User>();
		JdoQueryHelper qh = JdoQueryHelper.newQuery(pm, User.class);

		if (filterText != null) {
			qh.andParams("userEmail.startsWith(%s)", filterText);
		}

		if (excludeLoggedUser && this.getLoggedUserInfo() != null && this.getLoggedUserInfo().isLogged()
				&& this.getLoggedUserInfo().getUserId() != null) {
			qh.andParams("userEmail!=%s", this.getLoggedUserInfo().getUserEmail());
		}

		qh.and("fakeUser==%s", false);

		qh.setResult("count(this)");
		Long total = (Long) qh.execute();

		qh.setRange(start, start + length);
		qh.setResult("this");

		@SuppressWarnings("unchecked")
		List<User> users = (List<User>) qh.execute();

		page.setTotal(total != null ? total.longValue() : 0l);
		page.setElements(users);

		logger.info("... got page {0}", page);

		return page;

	}

}
